package org.asiainfo.system.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import org.asiainfo.common.core.constant.TenantConstants;
import org.asiainfo.common.idempotent.annotation.RepeatSubmit;
import org.asiainfo.common.log.annotation.Log;
import org.asiainfo.common.log.enums.BusinessType;
import org.asiainfo.common.tenant.utils.TenantHelper;
import org.springframework.validation.annotation.Validated;
import org.asiainfo.system.service.SysTenantService;
import org.asiainfo.system.domain.vo.SysTenantVo;
import org.asiainfo.system.domain.bo.SysTenantBo;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.asiainfo.common.mybatis.stream.core.page.PageQuery;
import org.asiainfo.common.mybatis.stream.core.page.TableDataInfo;
import org.asiainfo.common.core.domain.R;
import org.asiainfo.common.web.core.BaseController;
import jakarta.validation.constraints.*;
import org.asiainfo.common.core.validate.AddGroup;
import org.asiainfo.common.core.validate.EditGroup;

import java.util.List;

/**
 * 租户表
 *
 * @author dotor-ww
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/tenant")
public class SysTenantController extends BaseController {

    private final SysTenantService sysTenantService;

    /**
     * 分页查询
     *
     * @param sysTenantBo 筛选条件
     * @param pageQuery   分页对象
     * @return 查询结果
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:list")
    @GetMapping("/list")
    public TableDataInfo<SysTenantVo> list(SysTenantBo sysTenantBo, PageQuery pageQuery) {
        return sysTenantService.queryPageList(sysTenantBo, pageQuery);
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:query")
    @GetMapping("/{id}")
    public R<SysTenantVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable("id") Long id) {
        return R.ok(sysTenantService.queryById(id));
    }

    /**
     * 新增数据
     *
     * @param sysTenantBo 实体
     * @return 新增结果
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:add")
    @Log(title = "租户表", businessType = BusinessType.INSERT)
    @RepeatSubmit
    @PostMapping
    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysTenantBo sysTenantBo) {
        if (sysTenantService.checkCompanyNameUnique(sysTenantBo)) {
            return R.fail("新增租户'" + sysTenantBo.getCompanyName() + "'失败，公司名称已存在");
        }
        return toAjax(sysTenantService.insertByBo(sysTenantBo));
    }

    /**
     * 编辑数据
     *
     * @param sysTenantBo 实体
     * @return 编辑结果
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @Log(title = "租户表", businessType = BusinessType.UPDATE)
    @RepeatSubmit
    @PutMapping
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantBo sysTenantBo) {
        sysTenantService.checkTenantAllowed(sysTenantBo.getTenantId());
        if (sysTenantService.checkCompanyNameUnique(sysTenantBo)) {
            return R.fail("修改租户'" + sysTenantBo.getCompanyName() + "'失败，公司名称已存在");
        }
        return toAjax(sysTenantService.updateByBo(sysTenantBo));
    }

    /**
     * 删除数据
     *
     * @param ids 主键
     * @return 删除是否成功
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:remove")
    @Log(title = "租户表", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
        return toAjax(sysTenantService.deleteWithValidByIds(List.of(ids)));
    }

    /**
     * 修改租户状态
     *
     * @param sysTenantBo 租户信息
     * @return 修改结果
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @Log(title = "租户表", businessType = BusinessType.UPDATE)
    @RepeatSubmit
    @PostMapping("/changeStatus")
    public R<Void> changeStatus(@RequestBody SysTenantBo sysTenantBo) {
        sysTenantService.checkTenantAllowed(sysTenantBo.getTenantId());
        return toAjax(sysTenantService.updateTenantStatus(sysTenantBo));
    }

    /**
     * 动态切换租户
     *
     * @param tenantId 租户ID
     * @return 操作结果
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @GetMapping("/dynamic/{tenantId}")
    public R<Void> dynamicTenant(@NotNull(message = "租户ID不能为空") @PathVariable Long tenantId) {
        sysTenantService.dynamicTenant(tenantId);
        TenantHelper.setDynamic(tenantId, true);
        return R.ok();
    }

    /**
     * 清除动态租户
     *
     * @return 操作结果
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @GetMapping("/dynamic/clear")
    public R<Void> dynamicClear() {
        sysTenantService.dynamicTenant(null);
        TenantHelper.clearDynamic();
        return R.ok();
    }

    /**
     * 同步套餐
     *
     * @param tenantId  租户ID
     * @param packageId 套餐ID
     * @return 同步结果
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @Log(title = "租户表", businessType = BusinessType.UPDATE)
    @GetMapping("/syncTenantPackage")
    public R<Void> syncTenantPackage(@NotNull(message = "租户ID不能为空") Long tenantId,
                                     @NotNull(message = "套餐ID不能为空") Long packageId) {
        return toAjax(TenantHelper.ignore(() -> sysTenantService.syncTenantPackage(tenantId, packageId)));
    }
}

